#include <buola/net/gdata/cservice.h>
#include <buola/net/chttpform.h>
#include <buola/net/chttprequest.h>

#include <buola/algorithm/regex.h>
#include <buola/xml.h>

namespace buola { namespace io { namespace gdata {

CService::CService()
{

}

CService::~CService()
{

}

bool CService::Authenticate(const std::string &pName,const std::string &pPass)
{
    CHTTPForm lForm;
    lForm["accountType"]="HOSTED_OR_GOOGLE";
    lForm["Email"]=pName;
    lForm["Passwd"]=pPass;
    lForm["service"]=GetServiceAuthCode();
    lForm["source"]="buola";

    CHTTPRequest lRequest(uri("https://www.google.com/accounts/ClientLogin"));

    lRequest.SetPost(lForm);

    std::string lData;
    int lRet=lRequest.Perform(lData);

    mAuth.clear();

    if(lRet!=200) //login failed
    {
        throw XPermission("login failed in gdata service");
    }

    if(!simple_regex_search("Auth=([^\n\r]*)",lData,mAuth,1))
    {
        throw XPermission("no auth in reply from gdata service");
    }

    return true;
}

void CService::Query(const CURI &pURI,int pRedirects)
{
    CURI lURI=pURI;
    //if we have a session id and the query doesn't, insert it
    if(!mGSessionId.empty()&&!pURI.HasQueryItem("gsessionid"))
        lURI.AddQueryItem("gsessionid",mGSessionId);

    CHTTPRequest lRequest(lURI);
    lRequest.SetGet();

    if(IsAuthenticated())
        lRequest.AddHeader("Authorization","GoogleLogin auth="+mAuth);
    lRequest.AddHeader("GData-Version","2");

    std::string lData;
    int lRet=lRequest.Perform(lData);

    if(lRet==302) //redirect
    {
        CURI lRedirectURI=lRequest.GetRedirectURI();
        //extract the session id for the url, to use it in the future
        mGSessionId=lRedirectURI.GetQueryItem("gsessionid");
        return Query(lRedirectURI,pRedirects-1);
    }

    throw XNotImplemented("CServide::Query");
    ///\todo this!!!
//     xml::CDoc lDoc;
//     lDoc.SetAutoIndent(true);
//     lDoc.CollectFrom(lData);
//     lDoc.WriteTo(msg_info());
}

/*namespace gdata*/ } /*namespace io*/ } /*namespace buola*/ }
